import java.io.BufferedReader;
import java.io.DataInputStream;
import java.io.FileInputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.HashMap;


public class DataManager {
  private BufferedReader fileReader;
  private FileInputStream fstream;
  private DataInputStream inStream;
  
  public HashMap<Integer,ArrayList<State>> data;
  public ArrayList<State> states;
  public int year = 2010;
  public int stateIndex;
  public HashMap<Integer,HashMap<String,Float>> percentData;

	public DataManager(String path)
	{
        data = new HashMap<Integer, ArrayList<State>>();
        percentData = new HashMap<Integer,HashMap<String,Float>>();
		//String path = "C:\\Users\\danst_000\\SkyDrive\\Android Projects\\Project1\\src\\"; // figure out the working path...
		DataFile[] datafiles = 
		{
                  DataFile.data2010,
                  DataFile.data2009,
                  DataFile.data2008,
                  DataFile.data2007,
                  DataFile.data2006,
                  DataFile.data2005,
                  DataFile.data2004,
                  DataFile.data2003,
                  DataFile.data2002,
                  DataFile.data2001,
                  DataFile.percentFatalities

		};		
		
		for (DataFile filename : datafiles) 
		{					    
		    if(filename == DataFile.percentFatalities){
		    	readP(path,filename);
		    }
		    else{
		    	data.put(year, readDataFile(path, filename)); //add year to output hash map
			    percentData.put(year,new HashMap<String,Float>());
			    System.out.println("Read data for " + year);
			    year--;
		    }
		}	

	}
	
	private void readP(String path, DataFile File){
		states = new ArrayList<State>();
		try
		{
			//String open = path+"/data/"+File.filename();
			//open= open.replace('\\', '/');
			//System.out.println(open);
			String file_path = String.format("%s%s", path, File.filename());
			  fstream = new FileInputStream(file_path);//getClass().getClassLoader().getResourceAsStream("data/"+File.filename());

			  inStream = new DataInputStream(fstream);
			  fileReader = new BufferedReader(new InputStreamReader(inStream));
			  String strLine;

			  
			  while ((strLine = fileReader.readLine()) != null)   
			  {
                            try
                            {
                              String[] LineSplit = strLine.split(",");
                              Integer year = Integer.parseInt(LineSplit[0]); 
                              String state = LineSplit[1];
                              Float percent = Float.parseFloat(LineSplit[2]);
                              
                              percentData.get(year).put(state, percent);
                                  
                            }
                            catch(Exception e){
                              System.out.println(e.toString());      
                            }        
			  }
			  //Close the input stream
			  inStream.close();
		}
		catch (Exception e)
		{//Catch exception if any			 
			System.err.println( e.toString() + "\n" + File.filename());
			System.exit(-1);
		}

	}
	
	private ArrayList<State> readDataFile(String path, DataFile File)
	{
          states = new ArrayList<State>();
		try
		{
			//String open = path+"/data/"+File.filename();
			//open= open.replace('\\', '/');
			//System.out.println(open);
			String file_path = String.format("%s%s", path, File.filename());
			  fstream = new FileInputStream(file_path);//getClass().getClassLoader().getResourceAsStream("data/"+File.filename());

			  inStream = new DataInputStream(fstream);
			  fileReader = new BufferedReader(new InputStreamReader(inStream));
			  String strLine;
                          String currentState = "";
                          int currentCase = 0;
			  while ((strLine = fileReader.readLine()) != null)   
			  {
                            try
                            {
                              String[] LineSplit = strLine.split(",");
                              currentState = LineSplit[0]; 
                  
                              //check if state is already stored
                              boolean stateExists = false;
                              for(int i = 0; i < states.size(); i++){
                                if(states.get(i).getName().equals(currentState)){ //state found
                                  stateExists = true;
                                  stateIndex = i;
                                }
                              }
                              if(!stateExists){ //create state if it does not exist
                                
                                HashMap<Integer,Case> cases = new HashMap<Integer,Case>(); 
                                ArrayList<Integer> caseNumbers = new ArrayList<Integer>();
                                State newState = new State(currentState, year, true, caseNumbers.size(), cases, caseNumbers);
                                
                                //create case
                                Case newCase = createCase(LineSplit);  
                                currentCase = newCase.id;
                                
                                //add person
                                Person newPerson = createPerson(LineSplit);
                                newCase.addPerson(newPerson);
                                //System.out.println("Age:"+age+" isMale: "+LineSplit[19]+" type: "+LineSplit[17]);
                                
                                //add vehicle
                                newCase.addVehicle(LineSplit[18]); //vehicle body type
                                
                                //add case to state
                                newState.cases.put(currentCase, newCase);
                                newState.caseNumbers.add(currentCase); //add case number
                                newState.insertCounty(newCase.county);                                
								  if(newState.countiesToCases.containsKey(newCase.county)){
									  newState.countiesToCases.get(newCase.county).add(currentCase);
								  }
								  else{
									  newState.countiesToCases.put(newCase.county, new ArrayList<Integer>());  
								  }
                                states.add(newState);
                                stateIndex = states.size() - 1; //remember the index of this state in the array                     
                              }
                              
                              else {//state already exists, just grab case and person
                                 
                              currentCase = Integer.parseInt(LineSplit[1]);
                              //System.out.println(currentCase);
                              
                              //check if case already exists
                              State tmpState = states.get(stateIndex);
                              if(tmpState.cases.get(currentCase) == null){ //case does not exist
                                //if(currentCase == 795){ System.out.println("Here is case 795 for state:"+stateIndex);}
                                Case newCase = createCase(LineSplit); //get rest of case info
                  
                                //add person
                                String age = LineSplit[14];
                                Person newPerson = createPerson(LineSplit);
                                newCase.addPerson(newPerson);
                                //System.out.println("Age:"+age+" isMale: "+LineSplit[19]+" type: "+LineSplit[17]);
                                  
                                //add vehicle
                                newCase.addVehicle(LineSplit[18]); //vehicle body type
                                  
                                tmpState.cases.put(currentCase, newCase);
                                tmpState.insertCounty(newCase.county);
							if(tmpState.countiesToCases.containsKey(newCase.county)){
								tmpState.countiesToCases.get(newCase.county).add(currentCase);
							}
							else{
								tmpState.countiesToCases.put(newCase.county, new ArrayList<Integer>());  
							}
                                tmpState.caseNumbers.add(currentCase);  
                                
                               }
                               else {//else case exists, just grab person info
                                Person newPerson = createPerson(LineSplit);
                                tmpState.cases.get(currentCase).addPerson(newPerson);
                                //System.out.println("Age:"+age+" isMale: "+LineSplit[19]+" type: "+LineSplit[17]);
                                  
                                //add vehicle
                                tmpState.cases.get(currentCase).addVehicle(LineSplit[18]);              
                                }
                              }
                            }
                  
                            catch(Exception e){
                              System.out.println(e.toString());      
                            }        
			  }
			  //Close the input stream
			  inStream.close();
		}
		catch (Exception e)
		{//Catch exception if any			 
			System.err.println( e.toString() + "\n" + File.filename());
			System.exit(-1);
		}
                return states;
	}

  public Person createPerson(String[] LineSplit){
      String age = LineSplit[14];
      String gender = LineSplit[17];
      String personType = LineSplit[15];
      String drugs = LineSplit[16];
      String alcohol = LineSplit[19];
      Person newPerson = new Person(age, gender, personType, drugs, alcohol);
      return newPerson;
  }
  
  public Case createCase(String[] LineSplit){
      int currentCase = Integer.parseInt(LineSplit[1]);
      double latitude = Double.parseDouble(LineSplit[9]);
      double longitude = Double.parseDouble(LineSplit[11]);
      String county = LineSplit[2];    
      String atmosphere = LineSplit[3];
      String hour = LineSplit[5];
      String month = LineSplit[6];
      String time = LineSplit[7];
      String day = LineSplit[8];
      String light = LineSplit[10];
      int fatalities = Integer.parseInt(LineSplit[12]);
      String speeding = LineSplit[13];
      
      Case newCase = new Case(currentCase, year, latitude, longitude, atmosphere, light, hour, month, time, day, fatalities, speeding, county); 
      
      return newCase;
  }

}
